﻿using EnvCommonUtility;
using Microsoft.Practices.Prism.Commands;
using Microsoft.Practices.Prism.Events;
using InteractiveWhiteboardManagement.Base.Events;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel.DataAnnotations;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using TreeMgtModule.Views;
using System.Windows.Media;
using EnvControlLib;
using System.Windows.Input;
using RemotingObject;
using Microsoft.Practices.Prism.Regions;
using InteractiveWhiteboardManagement.Base.Common;
using Microsoft.Practices.ServiceLocation;
using System.Windows.Media.Imaging;
using System.Windows.Threading;
using System.Net.NetworkInformation;
using System.Threading;
using InteractiveWhiteboardManagement.Base.ViewModels;
using DAL;
using CommonBase;

namespace TreeMgtModule.ViewModels
{
    /// <summary>
    /// 类别树
    /// </summary>
    public class ViewModel_CategoryTree : WorkspaceViewModel
    {
        #region Private Fields

        private DelegateCommand<string> _cmdMenuItemClick;
        private TreeView _treeCategory;
        private ITreeGroup _selectedTreeNode; // 所选结点
        private IWMDal _dataOperation = new IWMDal();
        private System.Timers.Timer _timerConnectionState; // 网络连接状态

        private static readonly object _padlock = new Object();
        private readonly IRegionManager _regionManager;
        private readonly IServiceLocator _serviceLocator;

        #endregion

        #region Constructor

        public ViewModel_CategoryTree(IRegionManager regionManager, IServiceLocator serviceLocator)
        {
            try
            {
                this._regionManager = regionManager;
                this._serviceLocator = serviceLocator;

                TreeViewOperation _treeOpertion = new TreeViewOperation();
                TreeGroupModel node = new TreeGroupModel(string.Empty, new ObservableCollection<ITreeGroup>());
                _treeOpertion.AddTreeView("0", node, (TreeGroupModel)null); // 获取树节点，构建设备树
                TreeViewSource = node.Leaves; // 绑定到树资源

                #region 获取分类统计界面
                View_CategoryStatistics statistics = this._serviceLocator.GetInstance<Object>(ViewNames.TreeMgtModule_CategoryStatistics) as View_CategoryStatistics; // 解析分类统计页面
                ViewModel_CategoryStatistics vm_Statistics = statistics.DataContext as ViewModel_CategoryStatistics;
                #endregion

                #region Timer Connection State
                _timerConnectionState = new System.Timers.Timer();
                _timerConnectionState.Interval = EnvUtilities.TimerHeartbeat * 1000; // 以毫秒为单位
                _timerConnectionState.Elapsed += (s, arg) =>
                {
                    try
                    {
                        if (TreeViewSource != null && TreeViewSource.Count > 0)
                        {
                            lock (_padlock)
                            {
                                int leafSumCount = 0, leafOKCount = 0, leafConnectionCount = 0,
                                    leafDisconnectionCount = 0, leafWrongCount = 0;

                                _checkConnectionState(TreeViewSource,
                                    ref leafSumCount, ref leafOKCount,
                                    ref leafConnectionCount, ref leafDisconnectionCount,
                                    ref leafWrongCount); // 检查网络状态

                                if (vm_Statistics != null) // 更新前台统计显示
                                {
                                    vm_Statistics.LeafSumCount = leafSumCount;
                                    vm_Statistics.LeafOKCount = leafOKCount;
                                    vm_Statistics.LeafConnectionCount = leafConnectionCount;
                                    vm_Statistics.LeafDisconnectionCount = leafDisconnectionCount;
                                    vm_Statistics.LeafWrongCount = leafWrongCount;
                                }
                            }
                        }
                    }
                    catch (System.Exception ex)
                    {
#if DEBUG
                        Debug.WriteLine(ex.Message);
#endif
                    }
                };
                _timerConnectionState.Start();
                #endregion
            }
            catch (System.Exception ex)
            {
#if DEBUG
                Debug.WriteLine(ex.Message);
#endif
                MessageBox.Show(ex.Message, ConstantString.MSG_COMPANY);
            }
        }

        #endregion

        #region Public Property

        /// <summary>
        /// 绑定树资源
        /// </summary>
        public ObservableCollection<ITreeGroup> TreeViewSource { get; set; }

        /// <summary>
        /// 右键菜单选择
        /// </summary>
        [Display(GroupName = "DelegateCommand")]
        public DelegateCommand<string> Cmd_MenuItemClick
        {
            get
            {
                if (_cmdMenuItemClick == null)
                {
                    _cmdMenuItemClick = new DelegateCommand<string>(_menuItemClick, _canMenuItemClick);
                }
                return _cmdMenuItemClick;
            }
        }

        #endregion

        #region Event

        /// <summary>
        /// 右键菜单的显示【Tree 右键菜单】
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        public void TreeView_ContextMenuOpening(object sender, ContextMenuEventArgs e)
        {
            try
            {
                if (sender is TreeView)
                {
                    _treeCategory = sender as TreeView; // 记录设备树
                    _selectedTreeNode = _treeCategory.SelectedItem as ITreeGroup; // 记录所选结点，注：TreeView 没有 SelectedItem 公开 setter 属性，只有 getter 访问器！

                    if (_selectedTreeNode == null)
                    {
                        e.Handled = true;
                        return;
                    }

                    (_treeCategory.ContextMenu.Items[0] as MenuItem).IsEnabled = false; // 监控界面
                    (_treeCategory.ContextMenu.Items[1] as MenuItem).IsEnabled = true;  // 刷新列表
                    (_treeCategory.ContextMenu.Items[2] as MenuItem).IsEnabled = true;  // 查看详情
                    (_treeCategory.ContextMenu.Items[3] as MenuItem).IsEnabled = true;  // 增加结点
                    (_treeCategory.ContextMenu.Items[4] as MenuItem).IsEnabled = true;  // 删除结点
                    (_treeCategory.ContextMenu.Items[5] as MenuItem).IsEnabled = false; // 查看课程表


                    if (_selectedTreeNode.Level == 0) // 根结点
                    {
                        (_treeCategory.ContextMenu.Items[4] as MenuItem).IsEnabled = false;  // 删除结点
                        return;
                    }

                    if (_selectedTreeNode.Leaves == null ||
                        (_selectedTreeNode.Leaves != null && _selectedTreeNode.Leaves.Count == 0)) // 叶子结点
                    {
                        (_treeCategory.ContextMenu.Items[0] as MenuItem).IsEnabled = true; // 监控界面
                        (_treeCategory.ContextMenu.Items[5] as MenuItem).IsEnabled = true; // 查看课程表
                        return;
                    }
                }
            }
            catch (System.Exception ex)
            {
#if DEBUG
                Debug.WriteLine(ex.Message);
#endif
            }
        }

        /// <summary>
        /// 双击叶子结点【Tree 右键菜单】
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        public void TreeView_MouseDoubleClick(object sender, MouseButtonEventArgs e)
        {
            try
            {
                // 显示监控界面
                if (sender is TreeView && (sender as TreeView).SelectedItem != null &&
                    (sender as TreeView).SelectedItem is ITreeGroup &&
                    ((sender as TreeView).SelectedItem as ITreeGroup).Arg != null &&
                    ((sender as TreeView).SelectedItem as ITreeGroup).Arg is TagModel &&
                    (((sender as TreeView).SelectedItem as ITreeGroup).Leaves == null ||
                    (((sender as TreeView).SelectedItem as ITreeGroup).Leaves != null &&
                    ((sender as TreeView).SelectedItem as ITreeGroup).Leaves.Count == 0))) // 只有叶子结点有效
                {
                    _selectedTreeNode = (sender as TreeView).SelectedItem as ITreeGroup; // 记录所选结点，注：TreeView 没有 SelectedItem 公开 setter 属性，只有 getter 访问器！
                    TagModel leafTag = ((sender as TreeView).SelectedItem as ITreeGroup).Arg as TagModel;

                    #region 判断 IP 合法性
                    if (string.IsNullOrWhiteSpace(leafTag.IP)) // 判 IP 是否填写
                    {
                        MessageBox.Show("IP 地址为空，请在详细界面中填写 IP 地址！", ConstantString.MSG_COMPANY);
                        return;
                    }
                    else if (!CommonClass.Utilities.ValidIP(leafTag.IP)) // 判 IP 是否合法
                    {
                        MessageBox.Show("IP 地址不合法！", ConstantString.MSG_COMPANY);
                        return;
                    }
                    #endregion

                    #region 判断客户端状态
                    if (leafTag.Status != LeafStatusEnum.LeafOK.ToString()) // 只有网络连通且客户端运行时才能执行监控
                    {
                        MessageBox.Show("客户端连接不成功！", ConstantString.MSG_COMPANY);
                        return;
                    }
                    #endregion

                    #region 监控中
                    View_MonitorScreen monitor = this._serviceLocator.GetInstance<Object>(ViewNames.TreeMgtModule_MonitorScreen) as View_MonitorScreen; // 解析当前监控页面
                    ViewModel_MonitorScreen vm_MonitorScreen = monitor.DataContext as ViewModel_MonitorScreen;
                    vm_MonitorScreen.MonitorTitle = string.Format("当前监控：{0}", _getFullLeafPath(_selectedTreeNode)); // 获取当前监控信息
                    if (_selectedTreeNode.RemoteMonitor == null) // 判断有无自己的远程代理对象
                    {
                        _selectedTreeNode.RemoteMonitor = MonitorOperation.Instance.GetObject(leafTag.IP); // Remote 代理对象
                    }
                    vm_MonitorScreen.RemoteMonitor = _selectedTreeNode.RemoteMonitor;
                    vm_MonitorScreen.WorkingTreeNode = _selectedTreeNode;

                    /* 注：RequestNavigate 时，若不是单例模式，每次都是新建一个实例
                    this._regionManager.RequestNavigate(RegionNames.ContentRegion, ViewNames.TreeMgtModule_MonitorScreen); // 显示指定页面
                     */
                    object view = this._regionManager.Regions[RegionNames.ContentRegion].GetView(vm_MonitorScreen.MonitorTitle); // 根据视图名获取对应视图
                    if (view == null) // 若找不到对应视图则添加
                    {
                        // 判断监控窗口个数
                        int monitorScreenCount = this._regionManager.Regions[RegionNames.ContentRegion].Views.Count(p => p.GetType().Name.Equals(ViewNames.TreeMgtModule_MonitorScreen)); // 获得监控窗口个数
                        if (monitorScreenCount >= EnvUtilities.TabCountMonitorScreen)
                        {
                            AutoCloseNoticeWindow.Show(string.Format("最多只能打开{0}个监控窗口",
                                EnvUtilities.TabCountMonitorScreen), false);
                            return;
                        }

                        this._regionManager.Regions[RegionNames.ContentRegion].Add(monitor, vm_MonitorScreen.MonitorTitle); // 添加新的视图到当前区域中 AddToRegion
                        view = monitor;
                    }
                    this._regionManager.Regions[RegionNames.ContentRegion].Activate(view); // 激活视图显示
                    #endregion
                }
            }
            catch (System.Exception ex)
            {
#if DEBUG
                Debug.WriteLine(ex.Message);
#endif
                MessageBox.Show(ex.Message, ConstantString.MSG_COMPANY);
            }
        }

        #endregion

        #region Private Methods

        #region DelegateCommand

        private bool _canMenuItemClick(string menu)
        {
            return true;
        }


        /// <summary>
        /// 右键菜单选择
        /// </summary>
        /// <param name="menu"></param>
        private void _menuItemClick(string menu)
        {
            try
            {
                switch (menu)
                {
                    case "MonitorScreen": // 监控界面
                        TreeView_MouseDoubleClick(_treeCategory, null);
                        break;
                    case "RefreshTree": // 刷新列表
                        _refreshTree();
                        break;
                    case "ShowDetail": // 查看详情
                        _showDetail();
                        break;
                    case "ShowSyllabus": // 查看课程表
                        _showSyllabus();
                        break;
                    case "AddNode": // 增加结点
                        _addNode();
                        break;
                    case "DeleteNode": // 删除结点
                        _deleteNode();
                        break;



                    default:
                        break;
                }
            }
            catch (System.Exception ex)
            {
#if DEBUG
                Debug.WriteLine(ex.Message);
#endif
            }
        }

        #endregion

        /// <summary>
        /// 刷新列表【Tree 右键菜单】
        /// </summary>
        private void _refreshTree()
        {
            new Thread(() =>
            {
                try
                {
                    if (TreeViewSource != null && TreeViewSource.Count > 0)
                    {
                        lock (_padlock)
                        {
                            int leafSumCount = 0, leafOKCount = 0, leafConnectionCount = 0,
                                    leafDisconnectionCount = 0, leafWrongCount = 0;

                            _checkConnectionState(TreeViewSource,
                                ref leafSumCount, ref leafOKCount,
                                ref leafConnectionCount, ref leafDisconnectionCount,
                                ref leafWrongCount); // 检查网络状态
                        }
                    }
                }
                catch (System.Exception ex)
                {
#if DEBUG
                    Debug.WriteLine(ex.Message);
#endif
                }
            }).Start();
        }

        /// <summary>
        /// 查看详情【Tree 右键菜单】
        /// </summary>
        private void _showDetail()
        {
            if (_selectedTreeNode == null)
                return;

            Window info = new Window()
            {
                Topmost = true,
                Width = 910,
                Height = 250,
                Title = "详情窗口【修改结点信息】",
                WindowStartupLocation = WindowStartupLocation.CenterScreen,
                Style = Application.Current.Resources.MergedDictionaries[0][Application.Current.Resources["FormWindowStyle"].ToString()] as Style,
            };

            string oldIP = string.Empty; // 修改前的 IP
            if (_selectedTreeNode != null &&
                _selectedTreeNode.Arg != null &&
                _selectedTreeNode.Arg is TagModel)
            {
                oldIP = (_selectedTreeNode.Arg as TagModel).IP; // 记录修改前的 IP 地址
            }

            View_CategoryDetail view = new View_CategoryDetail();
            view.DataContext = new ViewModel_CategoryDetail(info, _selectedTreeNode, false);

            info.Content = view;
            info.Closed += (s, e) =>
            {
                try
                {
                    Window win = s as Window;
                    if (win.DialogResult.HasValue && win.DialogResult.Value)
                    {
                        ITreeGroup node = ((win.Content as View_CategoryDetail).DataContext as ViewModel_CategoryDetail).WorkingTreeNode;

                        if (node != null && node.Arg != null &&
                            node.Arg is TagModel)
                        {
                            TagModel nodeTag = node.Arg as TagModel;
                            int result = _dataOperation.EditTreeNodeItem("db_VWMSConnectionString",
                                "InteractiveWhiteboardManagement.exe",
                                nodeTag.ID, nodeTag.ParentID, nodeTag.Name, nodeTag.Address, nodeTag.IP,
                                nodeTag.Port, nodeTag.Status, nodeTag.Teacher, nodeTag.Remark);

                            if (result > 0)
                            {
                                _selectedTreeNode.Name = _selectedTreeNode.TooltipText = nodeTag.Name;
                                if (!oldIP.Equals(nodeTag.IP)) // IP 有更改，重新获取远程代理对象
                                {
                                    node.RemoteMonitor = MonitorOperation.Instance.GetObject(nodeTag.IP); // Remote 代理对象
                                }

                                MessageBox.Show("操作成功！", ConstantString.MSG_COMPANY);
                            }
                            else
                                MessageBox.Show("操作失败！", ConstantString.MSG_COMPANY);
                        }
                    }
                }
                catch (System.Exception ex)
                {
#if DEBUG
                    Debug.WriteLine(ex.Message);
#endif
                }
            };
            info.ShowDialog();


        }

        /// <summary>
        /// 查看课程表【Tree 右键菜单】
        /// </summary>
        private void _showSyllabus()
        {
            if (_selectedTreeNode == null ||
                _selectedTreeNode.Arg == null ||
                !(_selectedTreeNode.Arg is TagModel))
                return;

            Window info = new Window()
            {
                Topmost = true,
                Width = 1200,
                Height = 300,
                Title = "课程表",
                WindowStartupLocation = WindowStartupLocation.CenterScreen,
                Style = Application.Current.Resources.MergedDictionaries[0][Application.Current.Resources["FormWindowStyle"].ToString()] as Style,
                ResizeMode = ResizeMode.CanResizeWithGrip,
            };

            View_SyllabusDetail view = new View_SyllabusDetail();
            view.DataContext = new ViewModel_SyllabusDetail(info,
                (_selectedTreeNode.Arg as TagModel).ID);

            info.Content = view;
            info.Closed += (s, e) =>
            {
                try
                {
                    ViewModel_SyllabusDetail vm_Syllabus = ((s as Window).Content as View_SyllabusDetail).DataContext as ViewModel_SyllabusDetail;
                    ObservableCollection<SyllabusModel> syllabusList = vm_Syllabus.SyllabusList;
                    // 添加附加属性
                    for (int i = 0; i < syllabusList.Count; i++)
                    {
                        if (string.IsNullOrWhiteSpace(syllabusList[i].ClassID))
                            syllabusList[i].ClassID = (_selectedTreeNode.Arg as TagModel).ID;

                        if (syllabusList[i].Order != i)
                            syllabusList[i].Order = i;
                    }

                    // 对比是否值有变化
                    string newXML = CommonClass.XMLSerializer.SerializeXML(syllabusList);
                    if (!string.IsNullOrWhiteSpace(vm_Syllabus.SyllabusSerializeXML) &&
                        !string.IsNullOrWhiteSpace(newXML) &&
                        !vm_Syllabus.SyllabusSerializeXML.Equals(newXML)) // 已修改课程表时，存库！
                    {
                        int deleteResult = _dataOperation.DeleteSyllabusItem("db_VWMSConnectionString",
                            "InteractiveWhiteboardManagement.exe", (_selectedTreeNode.Arg as TagModel).ID);

                        if (deleteResult > 0)
                        {
                            int addResult = _dataOperation.AddSyllabusItem("db_VWMSConnectionString",
                                "InteractiveWhiteboardManagement.exe", syllabusList);

                            if (addResult > 0)
                            {
#if DEBUG
                                Debug.WriteLine("更新课程表成功！");
#endif
                                //MessageBox.Show("操作成功！", Utilities.MSG_COMPANY);
                            }
                            else
                                MessageBox.Show("操作失败！", ConstantString.MSG_COMPANY);
                        }
                        else
                            MessageBox.Show("操作失败！", ConstantString.MSG_COMPANY);
                    }
                }
                catch (System.Exception ex)
                {
#if DEBUG
                    Debug.WriteLine(ex.Message);
#endif
                }
            };
            info.ShowDialog();
        }

        /// <summary>
        /// 增加结点【Tree 右键菜单】
        /// </summary>
        private void _addNode()
        {
            if (_selectedTreeNode == null)
                return;

            Window info = new Window()
            {
                Topmost = true,
                Width = 910,
                Height = 250,
                Title = "详情窗口【添加结点信息】",
                WindowStartupLocation = WindowStartupLocation.CenterScreen,
                Style = Application.Current.Resources.MergedDictionaries[0][Application.Current.Resources["FormWindowStyle"].ToString()] as Style,
            };

            View_CategoryDetail view = new View_CategoryDetail();
            view.DataContext = new ViewModel_CategoryDetail(info, _selectedTreeNode, true);

            info.Content = view;
            info.Closed += (s, e) =>
            {
                try
                {
                    Window win = s as Window;
                    if (win.DialogResult.HasValue && win.DialogResult.Value)
                    {
                        ITreeGroup node = ((win.Content as View_CategoryDetail).DataContext as ViewModel_CategoryDetail).WorkingTreeNode;

                        if (node != null && node.Arg != null &&
                            node.Arg is TagModel)
                        {
                            TagModel nodeTag = node.Arg as TagModel;
                            int result = _dataOperation.AddTreeNodeItem("db_VWMSConnectionString",
                                "InteractiveWhiteboardManagement.exe",
                                nodeTag.ID, nodeTag.ParentID, nodeTag.Name, nodeTag.Address, nodeTag.IP,
                                nodeTag.Port, nodeTag.Status, nodeTag.Teacher, nodeTag.Remark);

                            if (result > 0)
                            {
                                node.Name = node.TooltipText = nodeTag.Name;
                                _selectedTreeNode.Leaves.Add(node);
                                if (_selectedTreeNode.Arg != null &&
                                    _selectedTreeNode.Arg is TagModel) // 去掉父结点前的图标与状态
                                {
                                    _selectedTreeNode.LeafSource = null;
                                    (_selectedTreeNode.Arg as TagModel).Status = string.Empty;
                                }
                                MessageBox.Show("操作成功！", ConstantString.MSG_COMPANY);
                            }
                            else
                                MessageBox.Show("操作失败！", ConstantString.MSG_COMPANY);
                        }
                    }
                }
                catch (System.Exception ex)
                {
#if DEBUG
                    Debug.WriteLine(ex.Message);
#endif
                }
            };
            info.ShowDialog();
        }

        /// <summary>
        /// 删除结点【Tree 右键菜单】
        /// </summary>
        private void _deleteNode()
        {
            if (_selectedTreeNode == null)
                return;

            ConfirmWindow cw = new ConfirmWindow("你想级联删除这个条目吗？");
            cw.Closed += new EventHandler(_cw_Closed);
            cw.ShowDialog();
        }

        /// <summary>
        /// 关闭事件
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void _cw_Closed(object sender, EventArgs e)
        {
            if ((sender as ConfirmWindow).DialogResult != true)
                return;

            try
            {
                List<ITreeGroup> deleteList = new List<ITreeGroup>()
                {
                    _selectedTreeNode,
                };
                _getChildren(_selectedTreeNode.Leaves, deleteList); // 获得所有孩子结点列表，级联删除！

                int result = _dataOperation.DeleteTreeNodeItem("db_VWMSConnectionString",
                    "InteractiveWhiteboardManagement.exe", deleteList);
                if (result > 0)
                {
                    _selectedTreeNode.Parent.Leaves.Remove(_selectedTreeNode);
                    if (_selectedTreeNode.Parent.Leaves.Count == 0)
                    {
#if DEBUG
                        Debug.WriteLine("不存在孩子结点。");
#endif
                    }
                    MessageBox.Show("操作成功！", ConstantString.MSG_COMPANY);
                }
                else
                    MessageBox.Show("操作失败！", ConstantString.MSG_COMPANY);
            }
            catch (Exception ex)
            {
#if DEBUG
                Debug.WriteLine(ex.Message);
#endif
            }
        }


        /// <summary>
        /// 获取<see cref="certainNode"/>所有孩子结点，不含自己，用以级联删除情况
        /// </summary>
        /// <param name="certainNode">当前结点</param>
        /// <param name="childrenList">孩子结点列表，用于添加孩子信息到列表中</param>
        private void _getChildren(ObservableCollection<ITreeGroup> certainNode,
            List<ITreeGroup> childrenList)
        {
            if (certainNode == null ||
                (certainNode != null && certainNode.Count <= 0))
                return;

            if (childrenList == null)
                childrenList = new List<ITreeGroup>();

            foreach (ITreeGroup treeNode in certainNode)
            {
                childrenList.Add(treeNode); // 添加孩子信息到列表中
                _getChildren(treeNode.Leaves, childrenList);
            }
        }

        /// <summary>
        /// 判断网络连接状态，心跳检测
        /// </summary>
        /// <param name="certainNode">分类树</param>
        /// <param name="leafSumCount">共有设备</param>
        /// <param name="leafOKCount">正在使用</param>
        /// <param name="leafConnectionCount">停止使用</param>
        /// <param name="leafDisconnectionCount">断开连接</param>
        /// <param name="leafWrongCount">错误 IP</param>
        private void _checkConnectionState(ObservableCollection<ITreeGroup> certainNode,
            ref int leafSumCount, ref int leafOKCount, ref int leafConnectionCount,
            ref int leafDisconnectionCount, ref int leafWrongCount)
        {
            if (certainNode == null ||
                (certainNode != null && certainNode.Count <= 0))
                return;

            TagModel leafTag;
            PingReply reply; // Ping 返回值
            bool isLeafOK = false; // 判断是否心跳正常
            string leafStatus = string.Empty; // 叶子状态

            try
            {
                for (int i = 0; i < certainNode.Count; i++)
                {
                    if ((certainNode[i].Leaves == null ||
                        (certainNode[i].Leaves != null && certainNode[i].Leaves.Count == 0)) &&
                        certainNode[i].Arg != null && certainNode[i].Arg is TagModel) // 只有叶子结点有效
                    {
                        leafSumCount++; // 设备总数
                        isLeafOK = false;
                        leafTag = certainNode[i].Arg as TagModel;

                        if (!CommonClass.Utilities.ValidIP(leafTag.IP)) // 解析 IP 不成功时
                        {
                            leafStatus = LeafStatusEnum.LeafWrong.ToString();
                            leafWrongCount++; // 错误 IP
                        }
                        else // 解析 IP 成功！
                        {
                            if (certainNode[i].RemoteMonitor == null)
                            {
                                certainNode[i].RemoteMonitor =
                                    MonitorOperation.Instance.GetObject(leafTag.IP); // Remote 代理对象
                            }

                            try
                            {
                                if (MonitorOperation.Instance.Heartbeat(certainNode[i].RemoteMonitor)) // 心跳检测正常，说明一切正常！
                                {
                                    leafStatus = LeafStatusEnum.LeafOK.ToString();
                                    isLeafOK = true;
                                    leafOKCount++; // 正在使用
                                }
                            }
                            catch (System.Exception ex)
                            {
#if DEBUG
                                Debug.WriteLine(ex.Message);
#endif
                            }
                            finally
                            {
                                if (!isLeafOK) // 心跳不正常时，再判断网络是否正常
                                {
                                    reply = CommonClass.Utilities.PingCommand(leafTag.IP);
                                    if (reply != null && reply.Status == IPStatus.Success) // 网络正常
                                    {
                                        leafStatus = LeafStatusEnum.LeafConnection.ToString();
                                        leafConnectionCount++; // 停止使用
                                    }
                                    else
                                    {
                                        leafStatus = LeafStatusEnum.LeafDisconnection.ToString();
                                        leafDisconnectionCount++; // 断开连接
                                    }
                                }
                            }
                        }

                        Application.Current.Dispatcher.Invoke((Action)(() => // 更新前台显示
                        {
                            if (string.IsNullOrWhiteSpace(leafStatus) ||
                                i >= certainNode.Count)
                                return;

                            leafTag.Status = leafStatus; // 叶子状态
                            certainNode[i].LeafSource = new BitmapImage(new Uri(
                                string.Format(ConstantString.IMAGE_URL, leafTag.Status), UriKind.RelativeOrAbsolute)); // 图片资源

                            // 若监控中且连接状态不正常时，则停止不正常的监控界面
                            /* 只关闭当前激活的不正常监控窗口
                            if (this._regionManager.Regions[RegionNames.ContentRegion].ActiveViews.Count() == 1) // 当前激活的 Tab，只有一个
                                currentMonitor = this._regionManager.Regions[RegionNames.ContentRegion].ActiveViews.FirstOrDefault()
                                    as View_MonitorScreen; // 解析当前监控页面
                             */
                            foreach (View_MonitorScreen currentMonitor in
                                this._regionManager.Regions[RegionNames.ContentRegion].Views.Where(p => p.GetType().Name.Equals(ViewNames.TreeMgtModule_MonitorScreen))) // 获得监控窗口
                            {
                                if (leafTag.Status != LeafStatusEnum.LeafOK.ToString() &&
                                    currentMonitor != null)
                                {
                                    ViewModel_MonitorScreen vm_MonitorScreen = currentMonitor.DataContext as ViewModel_MonitorScreen;

                                    if (vm_MonitorScreen != null && vm_MonitorScreen.Arg != null &&
                                        vm_MonitorScreen.Arg is TagModel && certainNode[i].Arg is TagModel &&
                                        (vm_MonitorScreen.Arg as TagModel).IP.Equals((certainNode[i].Arg as TagModel).IP))
                                    {
                                        string errMsg = string.Format("{0}{1}", "客户端连接不成功：",
                                            _getFullLeafPath(vm_MonitorScreen.WorkingTreeNode));
                                        vm_MonitorScreen.StopMonitor();
                                        vm_MonitorScreen.MonitorTitle = errMsg; // 提示错误信息
#if DEBUG
                                        Debug.WriteLine(errMsg);
#endif
                                        vm_MonitorScreen.CloseCommand.Execute(null); // 关闭当前 Tab
                                    }
                                }
                            }
                        }));
                    }
                    else if (certainNode[i].Arg != null && certainNode[i].Arg is TagModel) // 非叶子结点
                    {
                        (certainNode[i].Arg as TagModel).Status = string.Empty;
                        certainNode[i].LeafSource = null;
                    }

                    _checkConnectionState(certainNode[i].Leaves,
                        ref leafSumCount, ref leafOKCount,
                        ref leafConnectionCount, ref leafDisconnectionCount,
                        ref leafWrongCount); // 递归
                }
            }
            catch (System.Exception ex)
            {
#if DEBUG
                Debug.WriteLine(ex.Message);
#endif
            }
        }

        /// <summary>
        /// 获取<see cref="leaf"/>的完全路径
        /// </summary>
        /// <param name="leaf">叶子结点</param>
        private string _getFullLeafPath(ITreeGroup leaf)
        {
            if (leaf == null)
                return string.Empty;

            StringBuilder sbFullPath = new StringBuilder();
            sbFullPath.AppendLine(leaf.Name);

            ITreeGroup parent = leaf.Parent;
            while (parent != null) // 循环找父结点
            {
                sbFullPath.AppendLine(parent.Name);
                parent = parent.Parent;
            }

            string[] reversePath = sbFullPath.ToString().Split(new string[] { "\r\n" },
                StringSplitOptions.RemoveEmptyEntries); // 反序得到所有结点名称
            sbFullPath.Clear();
            // 重新组合新的完整路径
            for (int i = reversePath.Length - 1; i >= 0; i--)
            {
                sbFullPath.Append(reversePath[i]);
                sbFullPath.Append('-');
            }

            return sbFullPath.ToString().TrimEnd('-');
        }

        #endregion
    }
}
